#pragma once
#ifndef __HWINCONTROL_H__
#define __HWINCONTROL_H__

#include "hwindef.h"
#include "hwinmessage.h"
#include "hwinclass.h"
#include "hwinexception.h"
#include "hwincomponent.h"
#include "hwinkeys.h"
#include "hwinobj.h"
#include "hwinhandle.h"

namespace harlinn
{
    namespace windows
    {

        enum class MouseButton : int
        {
            Left = 0,
            Right = 1,
            Middle = 2
        };
        DEFINE_ENUM_FLAG_OPERATORS(MouseButton)

        enum class AnchorStyles : int
        {
            None = 0,
            Top = 1,
            Bottom = 2,
            Left = 4,
            Right = 8
        };
        DEFINE_ENUM_FLAG_OPERATORS(AnchorStyles)


        enum class HorizontalAlignment : int
        {
            Left = 0,
            Right = 1,
            Center = 2
        };


        enum class ContentAlignment
        {
            TopLeft = 1,
            TopCenter = 2,
            TopRight = 4,
            MiddleLeft = 16,
            MiddleCenter = 32,
            MiddleRight = 64,
            BottomLeft = 256,
            BottomCenter = 512,
            BottomRight = 1024
        };


        enum class DockStyle
        {
            // The control is not docked.
            None = 0,
            // The control's top edge is docked to the top of its containing control.
            Top = 1,
            // The control's bottom edge is docked to the bottom of its containing control.
            Bottom = 2,
            // The control's left edge is docked to the left edge of its containing control.
            Left = 3,
            // The control's right edge is docked to the right edge of its containing control.
            Right = 4,
            // All the control's edges are docked to the all edges of its containing control
            // and sized appropriately.
            Fill = 5,
        };
        


        class Control;
        // --------------------------------------------------------------------
        // Controls
        // --------------------------------------------------------------------
        class Controls
        {
            friend class Control; 
        public:
            typedef std::vector< std::weak_ptr< Control > > vector;

        private:
            vector items;
            Control* control;

            HWIN_EXPORT void DoOnHandleCreated( );
            HWIN_EXPORT void DoBeforeHandleDestroy( );
            HWIN_EXPORT void Remove(const std::shared_ptr< Control >& theControl);
            HWIN_EXPORT void Add(const std::shared_ptr< Control >& theControl);
            HWIN_EXPORT void DisconnectParentControl();

        public:
            HWIN_EXPORT Controls(Control* theControl);
            HWIN_EXPORT bool Contains(const std::shared_ptr< const Control >& theChildControl) const;
        };


        // --------------------------------------------------------------------
        // Control
        // --------------------------------------------------------------------
        class ComControl;
        class Control : public virtual Component 
        {
            friend class MessageDispatcherBase;
            friend class Controls;
            friend class ComControl;
            
            HWND handle;
            std::weak_ptr<Control> parentControl;

            Point position;
            harlinn::windows::Size size;

            LONG id;
            std::shared_ptr<Controls> controls;
            String text;
            bool automaticallyAddParentlessOwnedControls;

            AnchorStyles anchorStyles;
            bool enabled:1;
            bool visible:1;
            bool tabStop:1;
            bool recreatingHandle:1;

            DockStyle dock;

            WNDPROC originalWindowsProcedure;

        protected:
            HWIN_EXPORT static UINT REFLECTED_WM_COMMAND;
            HWIN_EXPORT static UINT REFLECTED_WM_NOTIFY;
            HWIN_EXPORT static UINT REFLECTED_WM_DRAWITEM;
            HWIN_EXPORT static UINT WM_GET_CONTROL; // 
        public:
            typedef Component Base;

            HWIN_EXPORT Control( );
            HWIN_EXPORT virtual ~Control();

        protected:
            HWIN_EXPORT virtual ComObject* CreateComObject() const;
            HWIN_EXPORT virtual void DoOnInitialize( );
        
            HWIN_EXPORT virtual std::shared_ptr<WindowClass> GetWindowClass() const;

            HWIN_EXPORT virtual DWORD GetStyle() const;
            HWIN_EXPORT virtual DWORD GetStyleEx() const;
        
            HWIN_EXPORT Control& SetWindowStyle(DWORD theStyle);
            HWIN_EXPORT Control& SetWindowStyleEx(DWORD theExStyle);

            bool IsRecreatingHandle() const { return recreatingHandle; };
            HWIN_EXPORT void RecreateHandle();
            HWIN_EXPORT virtual void DoOnBeforeRecreatingHandle();
            HWIN_EXPORT virtual void DoOnAfterRecreatingHandle();
        public:
            HWIN_EXPORT bool IsChild() const;
            HWIN_EXPORT bool IsToplevel() const;
            HWIN_EXPORT bool IsPopup() const;

            HWIN_EXPORT bool Enabled() const;
            HWIN_EXPORT Control& SetEnabled(bool theValue);

            HWIN_EXPORT bool Visible() const;
            HWIN_EXPORT Control& SetVisible(bool theValue);

            HWIN_EXPORT bool TabStop() const;
            HWIN_EXPORT Control& SetTabStop(bool theValue);
        protected:
            HWIN_EXPORT virtual void DoOnSetEnabled(bool theValue);
        public:
            HWIN_EXPORT long Id() const;
            HWIN_EXPORT Control& SetId(long theValue);

        protected:
            HWIN_EXPORT virtual HWND CreateHandle( );
            HWIN_EXPORT virtual void DoOnHandleCreated( );

            HWIN_EXPORT virtual void DestroyHandle( );
            HWIN_EXPORT virtual void DoBeforeHandleDestroy( );
        private:
            HWIN_EXPORT void DisconnectParentControl();

            HWIN_EXPORT Control& RestoreSubClassedWindowsProcedure();
            static LRESULT CALLBACK SubClassWndProc(HWND hWnd, UINT messageId, WPARAM wParam, LPARAM lParam);
        public:
            HWIN_EXPORT Control& SubClass(HWND hWnd);
            HWIN_EXPORT bool IsSubClassed() const;
        protected:
            HWIN_EXPORT virtual void DoOnWindowSubClassed( );
        public:

            HWIN_EXPORT HWND GetSafeHandle() const;
            HWIN_EXPORT bool IsHandleCreated() const;
        protected:
            HWIN_EXPORT virtual void HandleMessage(Message& message);

            HWIN_EXPORT static void RegisterControl(HWND hWnd,Control* constrol);
            HWIN_EXPORT static void UnregisterControl(HWND hWnd);
            HWIN_EXPORT static Control* GetControlFromHWND(HWND hWnd);
        public:
            HWIN_EXPORT const Control& GetClientRect(RECT* rectangle) const;
            HWIN_EXPORT const Control& GetClientRect(RECT& rectangle) const;
            HWIN_EXPORT RECT GetClientRect( ) const;
            HWIN_EXPORT D2D1_SIZE_F ClientSize() const;
            

            HWIN_EXPORT Control& SetParent(std::shared_ptr<Control> theParentControl);
            HWIN_EXPORT std::shared_ptr<Controls> Controls() const;
            HWIN_EXPORT std::shared_ptr<Control> Parent() const;
            HWIN_EXPORT bool HasParent() const;
            
            HWIN_EXPORT const Control& UpdateRect(RECT& updateRectangle) const;
            HWIN_EXPORT Control& UpdateRect(RECT& updateRectangle, bool erase);
            HWIN_EXPORT RECT UpdateRect( ) const;
            HWIN_EXPORT RECT UpdateRect( bool erase );


            //HWIN_EXPORT std::vector< Control* > GetChildren() const;


            HWIN_EXPORT bool IsChildOf(std::shared_ptr<const Control> theParentControl) const;
            HWIN_EXPORT bool IsChildOf(HWND theParentControl) const;

            HWIN_EXPORT bool IsParentOf(std::shared_ptr<const Control> theChildControl) const;
            HWIN_EXPORT bool IsParentOf(HWND theChildControl) const;

            HWIN_EXPORT bool IsValid() const;

            HWIN_EXPORT bool IsVisible() const;

            HWIN_EXPORT Control& InvalidateRect(bool erase = false);
            HWIN_EXPORT Control& InvalidateRect(const RECT& rectangle,bool erase = false);


            HWIN_EXPORT Control& MoveWindow(int x, int y, int width, int height, bool repaint = false);

            HWIN_EXPORT LONG SetWindowLong(int index, LONG theNewValue);
            HWIN_EXPORT LONG GetWindowLong(int index) const;

            HWIN_EXPORT LRESULT SendMessage(UINT Msg, WPARAM wParam = 0, LPARAM lParam = 0) const;
            HWIN_EXPORT const Control& PostMessage(UINT Msg, WPARAM wParam = 0, LPARAM lParam = 0) const;


            HWIN_EXPORT int TextLength() const;
            HWIN_EXPORT String Text() const;
            HWIN_EXPORT bool SetText(const String& text);
            HWIN_EXPORT bool SetText(const wchar_t* text);

            HWIN_EXPORT bool Show();
            HWIN_EXPORT bool ValidateRect(const RECT& rectangle);
            HWIN_EXPORT bool ValidateRect();

            HWIN_EXPORT harlinn::windows::Size Size() const;
            HWIN_EXPORT Control& SetSize(int width, int height);
            HWIN_EXPORT Control& SetSize(const harlinn::windows::Size& theSize);

            HWIN_EXPORT Point Position() const;
            HWIN_EXPORT Control& SetPosition(int x, int y);
            HWIN_EXPORT Control& SetPosition(const Point& thePosition);

            
            boost::signals2::signal<void (Control* sender, Message& message)> OnCancelMode;
            boost::signals2::signal<void (Control* sender, Message& message)> OnChar;
            boost::signals2::signal<void (Control* sender, Message& message)> OnCharToItem;
            boost::signals2::signal<void (Control* sender, Message& message)> OnClose;
            boost::signals2::signal<void (Control* sender, Message& message)> OnCompareItem;
            boost::signals2::signal<void (Control* sender, Message& message)> OnCommand;
            boost::signals2::signal<void (Control* sender, Message& message)> OnCopyData;
            boost::signals2::signal<void (Control* sender, Message& message)> OnDeadChar;
            boost::signals2::signal<void (Control* sender, Message& message)> OnDeleteItem;
            boost::signals2::signal<void (Control* sender, Message& message)> OnDestroy;
            boost::signals2::signal<void (Control* sender, Message& message)> OnDisplayChange;
            boost::signals2::signal<void (Control* sender, Message& message)> OnDrawItem;
            boost::signals2::signal<void (Control* sender, Message& message)> OnEnable;
            boost::signals2::signal<void (Control* sender, Message& message)> OnEnterSizeMove;
            boost::signals2::signal<void (Control* sender, Message& message)> OnEraseBackground;
            boost::signals2::signal<void (Control* sender, Message& message)> OnExitSizeMove;
            boost::signals2::signal<void (Control* sender, Message& message)> OnGetHotKey;
            boost::signals2::signal<void (Control* sender, Message& message)> OnGetText;
            boost::signals2::signal<void (Control* sender, Message& message)> OnGetTextLength;
            boost::signals2::signal<void (Control* sender, Message& message)> OnInitMenu;
            boost::signals2::signal<void (Control* sender, Message& message)> OnInitMenuPopup;
            boost::signals2::signal<void (Control* sender, Message& message)> OnKeyDown;
            boost::signals2::signal<void (Control* sender, Message& message)> OnKeyUp;
            boost::signals2::signal<void (Control* sender, Message& message)> OnKillFocus;
            boost::signals2::signal<void (Control* sender, Message& message)> OnMeasureItem;
            boost::signals2::signal<void (Control* sender, Message& message)> OnMenuCommand;
            boost::signals2::signal<void (Control* sender, Message& message)> OnMouseMove;
            boost::signals2::signal<void (Control* sender, Message& message)> OnMouseLeftButtonDown;
            boost::signals2::signal<void (Control* sender, Message& message)> OnMouseLeftButtonUp;
            boost::signals2::signal<void (Control* sender, Message& message)> OnMouseLeftButtonDoubleClick;
            boost::signals2::signal<void (Control* sender, Message& message)> OnMouseMiddleButtonDown;
            boost::signals2::signal<void (Control* sender, Message& message)> OnMouseMiddleButtonUp;
            boost::signals2::signal<void (Control* sender, Message& message)> OnMouseMiddleButtonDoubleClick;
            boost::signals2::signal<void (Control* sender, Message& message)> OnMouseRightButtonDown;
            boost::signals2::signal<void (Control* sender, Message& message)> OnMouseRightButtonUp;
            boost::signals2::signal<void (Control* sender, Message& message)> OnMouseRightButtonDoubleClick;
            boost::signals2::signal<void (Control* sender, Message& message)> OnMouseXButtonDown;
            boost::signals2::signal<void (Control* sender, Message& message)> OnMouseXButtonUp;
            boost::signals2::signal<void (Control* sender, Message& message)> OnMouseXButtonDoubleClick;
            boost::signals2::signal<void (Control* sender, Message& message)> OnMouseWheel;
            boost::signals2::signal<void (Control* sender, Message& message)> OnMove;
            boost::signals2::signal<void (Control* sender, Message& message)> OnMoving;
            boost::signals2::signal<void (Control* sender, Message& message)> OnNcActivate;
            boost::signals2::signal<void (Control* sender, Message& message)> OnNcCalcSize;
            boost::signals2::signal<void (Control* sender, Message& message)> OnNcDestroy;
            boost::signals2::signal<void (Control* sender, Message& message)> OnNotify;
            boost::signals2::signal<void (Control* sender, Message& message)> OnPaint;
            boost::signals2::signal<void (Control* sender, Message& message)> OnSetCursor;
            boost::signals2::signal<void (Control* sender, Message& message)> OnSetFocus;
            boost::signals2::signal<void (Control* sender, Message& message)> OnSetHotKey;
            boost::signals2::signal<void (Control* sender, Message& message)> OnSetRedraw;
            boost::signals2::signal<void (Control* sender, Message& message)> OnSetText;
            boost::signals2::signal<void (Control* sender, Message& message)> OnShowWindow;
            boost::signals2::signal<void (Control* sender, Message& message)> OnSize;
            boost::signals2::signal<void (Control* sender, Message& message)> OnSizing;
            boost::signals2::signal<void (Control* sender, Message& message)> OnSysChar;
            boost::signals2::signal<void (Control* sender, Message& message)> OnSysCommand;
            boost::signals2::signal<void (Control* sender, Message& message)> OnSysDeadChar;
            boost::signals2::signal<void (Control* sender, Message& message)> OnSysKeyDown;
            boost::signals2::signal<void (Control* sender, Message& message)> OnSysKeyUp;
            boost::signals2::signal<void (Control* sender, Message& message)> OnUniChar;
            boost::signals2::signal<void (Control* sender, Message& message)> OnVKeyToItem;
            boost::signals2::signal<void (Control* sender, Message& message)> OnWindowPosChanging;
            boost::signals2::signal<void (Control* sender, Message& message)> OnWindowPosChanged;

        protected:
            HWIN_EXPORT virtual bool IsInputChar(wchar_t charCode);
            HWIN_EXPORT virtual bool IsInputKey(Keys keyData);
            HWIN_EXPORT virtual bool ProcessMnemonic(wchar_t charCode);

            HWIN_EXPORT virtual void DoOnCancelMode(Message& message);
            HWIN_EXPORT virtual void DoOnChar(Message& message);
            HWIN_EXPORT virtual void DoOnCharToItem(Message& message);
            HWIN_EXPORT virtual void DoOnClose(Message& message);
            HWIN_EXPORT virtual void DoOnCompareItem(Message& message);
            HWIN_EXPORT virtual void DoOnCommand(Message& message);
            HWIN_EXPORT virtual void DoOnCopyData(Message& message);
            HWIN_EXPORT virtual void DoOnDeadChar(Message& message);
            HWIN_EXPORT virtual void DoOnDeleteItem(Message& message);
            HWIN_EXPORT virtual void DoOnDestroy(Message& message);
            HWIN_EXPORT virtual void DoOnDisplayChange(Message& message);
            HWIN_EXPORT virtual void DoOnDrawItem(Message& message);
            HWIN_EXPORT virtual void DoOnEnable(Message& message);
            HWIN_EXPORT virtual void DoOnEnterSizeMove(Message& message);
            HWIN_EXPORT virtual void DoOnEraseBackground(Message& message);
            HWIN_EXPORT virtual void DoOnExitSizeMove(Message& message);
            HWIN_EXPORT virtual void DoOnGetHotKey(Message& message);
            HWIN_EXPORT virtual void DoOnGetText(Message& message);
            HWIN_EXPORT virtual void DoOnGetTextLength(Message& message);
            HWIN_EXPORT virtual void DoOnInitMenu(Message& message);
            HWIN_EXPORT virtual void DoOnInitMenuPopup(Message& message);
            HWIN_EXPORT virtual void DoOnKeyDown(Message& message);
            HWIN_EXPORT virtual void DoOnKeyUp(Message& message);
            HWIN_EXPORT virtual void DoOnKillFocus(Message& message);
            HWIN_EXPORT virtual void DoOnMeasureItem(Message& message);
            HWIN_EXPORT virtual void DoOnMenuCommand(Message& message);
            HWIN_EXPORT virtual void DoOnMouseMove(Message& message);
            HWIN_EXPORT virtual void DoOnMouseLeftButtonDown(Message& message);
            HWIN_EXPORT virtual void DoOnMouseLeftButtonUp(Message& message);
            HWIN_EXPORT virtual void DoOnMouseLeftButtonDoubleClick(Message& message);
            HWIN_EXPORT virtual void DoOnMouseMiddleButtonDown(Message& message);
            HWIN_EXPORT virtual void DoOnMouseMiddleButtonUp(Message& message);
            HWIN_EXPORT virtual void DoOnMouseMiddleButtonDoubleClick(Message& message);
            HWIN_EXPORT virtual void DoOnMouseRightButtonDown(Message& message);
            HWIN_EXPORT virtual void DoOnMouseRightButtonUp(Message& message);
            HWIN_EXPORT virtual void DoOnMouseRightButtonDoubleClick(Message& message);
            HWIN_EXPORT virtual void DoOnMouseXButtonDown(Message& message);
            HWIN_EXPORT virtual void DoOnMouseXButtonUp(Message& message);
            HWIN_EXPORT virtual void DoOnMouseXButtonDoubleClick(Message& message);
            HWIN_EXPORT virtual void DoOnMouseWheel(Message& message);
            HWIN_EXPORT virtual void DoOnMove(Message& message);
            HWIN_EXPORT virtual void DoOnMoving(Message& message);
            HWIN_EXPORT virtual void DoOnNcActivate(Message& message);
            HWIN_EXPORT virtual void DoOnNcCalcSize(Message& message);
            HWIN_EXPORT virtual void DoOnNcDestroy(Message& message);
            HWIN_EXPORT virtual void DoOnNotify(Message& message);
            HWIN_EXPORT virtual void DoOnPaint(Message& message);
            HWIN_EXPORT virtual void DoOnSetCursor(Message& message);
            HWIN_EXPORT virtual void DoOnSetFocus(Message& message);
            HWIN_EXPORT virtual void DoOnSetHotKey(Message& message);
            HWIN_EXPORT virtual void DoOnSetRedraw(Message& message);
            HWIN_EXPORT virtual void DoOnSetText(Message& message);
            HWIN_EXPORT virtual void DoOnShowWindow(Message& message);
            HWIN_EXPORT virtual void DoOnSize(Message& message);
            HWIN_EXPORT virtual void DoOnSizing(Message& message);
            HWIN_EXPORT virtual void DoOnSysChar(Message& message);
            HWIN_EXPORT virtual void DoOnSysCommand(Message& message);
            HWIN_EXPORT virtual void DoOnSysDeadChar(Message& message);
            HWIN_EXPORT virtual void DoOnSysKeyDown(Message& message);
            HWIN_EXPORT virtual void DoOnSysKeyUp(Message& message);
            HWIN_EXPORT virtual void DoOnUniChar(Message& message);
            HWIN_EXPORT virtual void DoOnVKeyToItem(Message& message);
            HWIN_EXPORT virtual void DoOnWindowPosChanging(Message& message);
            HWIN_EXPORT virtual void DoOnWindowPosChanged(Message& message);
            


        };


        template< typename T >
        std::shared_ptr<T> make_control( )
        {
            HWIN_TRACE();
            auto result = std::make_shared<T>();
            result->Initialize( );
            return result;
        }

        template< typename T >
        std::shared_ptr<T> make_control(std::shared_ptr<Control> theParent)
        {
            HWIN_TRACE();
            auto result = std::make_shared<T>();
            result->SetParent( theParent );
            result->Initialize( theParent );
            return result;
        }

        template< typename T, typename A >
        std::shared_ptr<T> make_control(std::shared_ptr<Control> theParent, const A& argument)
        {
            HWIN_TRACE();
            auto result = std::make_shared<T>(argument);
            result->SetParent( theParent );
            result->Initialize( theParent );
            return result;
        }


        template< typename T, typename A1, typename A2 >
        std::shared_ptr<T> make_control(std::shared_ptr<Control> theParent, const A1& argument1, const A2& argument2)
        {
            HWIN_TRACE();
            auto result = std::make_shared<T>(argument1,argument2);
            result->SetParent( theParent );
            result->Initialize( theParent );
            return result;
        }



        // --------------------------------------------------------------------
        // MessageDispatcherBase
        // --------------------------------------------------------------------
        class MessageDispatcherBase
        {
        protected:
            static void HandleMessage(Control* theControl, Message& message)
            {
                theControl->HandleMessage(message);
            }

            static void RegisterControl(HWND hWnd, Control* theControl)
            {
                Control::RegisterControl(hWnd,theControl);
            }

            static void UnregisterControl(HWND hWnd)
            {
                Control::UnregisterControl(hWnd);
            }

        };


        // --------------------------------------------------------------------
        // ControlMessageDispatcher
        // --------------------------------------------------------------------
        template< typename ControlClass_ >
        class ControlMessageDispatcher : public MessageDispatcherBase
        {
        public:
            static LRESULT CALLBACK WndProc(HWND hWnd, UINT messageId, WPARAM wParam, LPARAM lParam)
            {
                HWIN_TRACE();
                Message message;
                message.hwnd = hWnd;
                message.message = messageId;
                message.wParam = wParam;
                message.lParam = lParam;
                message.time = GetMessageTime();
                DWORD pos = GetMessagePos();

                message.pt.x = GET_X_LPARAM(pos);
                message.pt.y = GET_Y_LPARAM(pos);

                LONG_PTR userData = (LONG_PTR)0;

                if(messageId == WM_NCCREATE)
                {
                    CREATESTRUCT* createStruct = (CREATESTRUCT*)lParam;
                    if(createStruct != nullptr)
                    {
                        userData = (LONG_PTR)createStruct->lpCreateParams;
                        if(userData)
                        {
                            SetWindowLongPtr(hWnd,GWLP_USERDATA,userData);
                            Control* control = (Control*)userData;
                            RegisterControl(hWnd,control);
                        }
                    }
                }
                else
                {
                    userData = GetWindowLongPtr(hWnd,GWLP_USERDATA);

                }

                if(userData)
                {
                    Control* control = (Control*)userData;

                    HandleMessage(control,message);
                    if(message.handled)
                    {
                        return message.result;
                    }
                }
                if(!message.handled)
                {
                    message.result = DefWindowProc(hWnd, message.message, message.wParam, message.lParam);
                }

                if(messageId == WM_NCDESTROY)
                {
                    UnregisterControl(hWnd);
                }

                return message.result;
            }
        };


        template< typename ControlClass_ >
        class SuperClassMessageDispatcher : public MessageDispatcherBase
        {
        public:
            static WNDPROC ControlProcedure;
            static LRESULT CALLBACK WndProc(HWND hWnd, UINT messageId, WPARAM wParam, LPARAM lParam)
            {
                HWIN_TRACE();
                Message message;
                message.hwnd = hWnd;
                message.message = messageId;
                message.wParam = wParam;
                message.lParam = lParam;
                message.time = GetMessageTime();
                DWORD pos = GetMessagePos();

                message.pt.x = GET_X_LPARAM(pos);
                message.pt.y = GET_Y_LPARAM(pos);

                LONG_PTR userData = (LONG_PTR)0;

                if(messageId == WM_NCCREATE)
                {
                    CREATESTRUCT* createStruct = (CREATESTRUCT*)lParam;
                    if(createStruct != nullptr)
                    {
                        userData = (LONG_PTR)createStruct->lpCreateParams;
                        if(userData)
                        {
                            SetWindowLongPtr(hWnd,GWLP_USERDATA,userData);
                            Control* control = (Control*)userData;
                            RegisterControl(hWnd,control);
                        }
                    }
                }
                else
                {
                    userData = GetWindowLongPtr(hWnd,GWLP_USERDATA);
                }

                if(userData)
                {
                    Control* control = (Control*)userData;

                    HandleMessage(control,message);
                    if(message.handled)
                    {
                        return message.result;
                    }
                }
                if(!message.handled)
                {
                    message.result = ControlProcedure(hWnd, message.message, message.wParam, message.lParam);
                }

                if(messageId == WM_NCDESTROY)
                {
                    UnregisterControl(hWnd);
                }

                return message.result;
            }
        };



    };
};




#endif //__HWINCONTROL_H__
